Импортируем OpenCV и прочее
import cv2
import statistics as st
import math
import time
from IPython.display import Image
from matplotlib import pyplot as plt
import numpy as np
print(cv2.__version__)
4.4.0
Добавляем изображения (Оригинальное и сжатое)
image_orig = cv2.imread("./PSNR-example-base.png") # Оригинальное
image_comp = cv2.imread("./PSNR-example-comp-90.jpg") # Сжатое
Изображения:
Image(data="./PSNR-example-base.png", width = 350)
Image(data="./PSNR-example-comp-90.jpg", width = 350)
Вычисляем PSNR
def psnr(image_1, image_2):
image_change = (image_1 - image_2) ** 2
MSE_R = st.fmean([pixel[0] for row in image_change for pixel in row])
MSE_G = st.fmean([pixel[1] for row in image_change for pixel in row])
MSE_B = st.fmean([pixel[2] for row in image_change for pixel in row])
MSE = (MSE_R + MSE_G + MSE_B) / 3
MAX_I = 2 ** 8
PSNR = 10 * math.log10(MAX_I ** 2 / MSE);
return PSNR
Искомая метрика:
psnr(image_orig, image_comp)
39.27874355280623
Считываем изображение
image = cv2.imread("hero-poster-full-hd.jpg")
Image(data="hero-poster-full-hd.jpg", width = 400)
Конвертируем в серый, использую cv2::cvtColor()
cv_start_time = time.time()
cv_gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv_end_time = time.time()
plt.imshow(cv_gray_image, cmap='gray', vmin = 0, vmax = 255)
<matplotlib.image.AxesImage at 0x165c2bb0>
Конвертируем в серый, используя average (R + G + B) / 3 фильтр
my_start_time = time.time()
for i in range(0, image.shape[0]):
for j in range(0, image.shape[1]):
pixel = image[i, j]
average = (int(pixel[0]) + int(pixel[1]) + int(pixel[2])) // 3
image[i, j] = average
my_end_time = time.time()
plt.imshow(image, cmap='gray', vmin = 0, vmax = 255)
<matplotlib.image.AxesImage at 0x15db4598>
Сравниваем полученные изображения, используя метрику psnr
image_change = cv_gray_image.copy()
for i in range(0, image.shape[0]):
for j in range(0, image.shape[1]):
image_change[i, j] = (int(image[i][j][0]) - int(image_change[i, j])) ** 2
MSE = st.fmean([pixel for row in image_change for pixel in row])
MAX_I = 2 ** 8
PSNR = 10 * math.log10(MAX_I ** 2 / MSE);
print(PSNR)
43.11458515041498
Время работы cv реализации
print(cv_end_time - cv_start_time)
0.007502079010009766
Время работы собственной реализации
print(my_end_time - my_start_time)
3.428194284439087
Выводы: собственная реализация по качеству и скорости работы сильно отстает от cv реализации
Загружаем изображение
image = cv2.imread("cat.JPG")
Image(data="./cat.JPG", width = 400)
image_yuv = cv2.cvtColor(image, cv2.COLOR_BGR2YUV)
plt.imshow(image_yuv)
<matplotlib.image.AxesImage at 0x163eaf40>
Теперь реализуем конвертацию. высчитываем компоненты
B, G, R = cv2.split(image)
Y = np.ndarray(shape=B.shape, dtype=B.dtype)
U = np.ndarray(shape=B.shape, dtype=B.dtype)
V = np.ndarray(shape=B.shape, dtype=B.dtype)
for i in range(0, image.shape[0]):
for j in range(0, image.shape[1]):
Y[i, j] = int(0.299 * R[i, j] + 0.587 * G[i, j] + 0.114 * B[i, j])
U[i, j] = int(-0.147 * R[i, j] - 0.289 * G[i, j] + 0.437 * B[i, j] + 128)
V[i, j] = int(0.615 * R[i, j] - 0.515 * G[i, j] - 0.09 * B[i, j] + 128)
Объединяем их в одно изображение
my_image_yuv = cv2.merge((Y, U, V))
plt.imshow(my_image_yuv)
<matplotlib.image.AxesImage at 0x164274a8>
Вычисляем меру сходства
psnr(image_yuv, my_image_yuv)
51.07281084690037
Конвертируем ищображение из YUV в RGB с помощью OpenCV
image_bgr = cv2.cvtColor(image_yuv, cv2.COLOR_YUV2RGB)
plt.imshow(image_bgr)
<matplotlib.image.AxesImage at 0x16457928>
Теперь реализуем конвертацию. высчитываем компоненты
Y, U, V = cv2.split(my_image_yuv)
B = np.ndarray(shape=Y.shape, dtype=Y.dtype)
G = np.ndarray(shape=Y.shape, dtype=Y.dtype)
R = np.ndarray(shape=Y.shape, dtype=Y.dtype)
for i in range(0, my_image_yuv.shape[0]):
for j in range(0, my_image_yuv.shape[1]):
R[i, j] = int(Y[i, j] + 1.13983 * (V[i, j] - 128))
G[i, j] = int(Y[i, j] - 0.39465 * (U[i, j] - 128) - 0.5806 * (V[i, j] - 128))
B[i, j] = int(Y[i, j] + 2.03211 * (U[i, j] - 128))
Объединяем их в одно изображение
my_image_bgr = cv2.merge((R, G, B))
plt.imshow(my_image_bgr)
<matplotlib.image.AxesImage at 0x16488da8>
Вычисляем меру сходства
PSNR = psnr(image_bgr, my_image_bgr)
PSNR
44.05398478715847
Функция увеличения яркости для BGR
def bright_bgr(source_image, value):
B, G, R = cv2.split(source_image)
for i in range(0, source_image.shape[0]):
for j in range(0, source_image.shape[1]):
B[i, j] += value
if B[i, j] > 255:
B[i, j] = 255
G[i, j] += value
if G[i, j] > 255:
G[i, j] = 255
R[i, j] += value
if R[i, j] > 255:
R[i, j] = 255
dest_image = cv2.merge((B, G, R))
return dest_image
Функция увеличения яркости для YUV
def bright_yuv(source_image, value):
Y, U, V = cv2.split(source_image)
for i in range(0, source_image.shape[0]):
for j in range(0, source_image.shape[1]):
Y[i, j] += value
if Y[i, j] > 255:
Y[i, j] = 255
dest_image = cv2.merge((Y, U, V))
return dest_image
start_time = time.time()
plt.imshow(bright_bgr(image, 15))
end_time = time.time()
print(end_time - start_time)
2.0209991931915283
start_time = time.time()
plt.imshow(bright_yuv(image_yuv, 20))
end_time = time.time()
print(end_time - start_time)
0.6959950923919678